package com.zeus.core.report;

import com.zeus.common.enums.ZeusEventTypeEnum;
import com.zeus.common.utils.StackTraceUtils;
import com.zeus.core.open.event.ZeusEvent;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.LogEvent;

import java.util.Objects;
import java.util.Optional;

/**
 * Log4j上报工具
 *
 * @author f1ybear_wang  2022/2/22 7:50 下午
 */
public class ZeusReportLog4j2Client extends AbstractLogZeusReportClient {

    /**
     * 日志信息
     */
    private LogEvent loggingEvent;

    public ZeusReportLog4j2Client(LogEvent event) {
        super();
        this.loggingEvent = event;
        this.zeusEvent = ZeusEvent.builder().eventType(eventType()).message(event.getMessage().getFormattedMessage()).build();
    }

    @Override
    public ZeusEventTypeEnum eventType() {
        return ZeusEventTypeEnum.LOG4J_EVENT;
    }

    @Override
    protected void parsingExtend() {
        if (this.parsingExtendInit || this.loggingEvent == null) {
            return;
        }
        // 初始化基础数据
        this.message = this.loggingEvent.getMessage().getFormattedMessage();
        this.loggerName = this.loggingEvent.getLoggerName();
        this.occurrenceTime = this.loggingEvent.getTimeMillis();
        // 初始化文件名、方法名、行号
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        for (StackTraceElement element : stackTrace) {
            if (element.getClassName().equals(loggingEvent.getLoggerName()) || loggingEvent.getLoggerName().contains(element.getClassName())) {
                loggerName = element.getClassName();
                methodName = element.getMethodName();
                fileName = element.getFileName();
                lineNumber = Objects.toString(element.getLineNumber(),null);
            }
        }


        // 获取异常
        Throwable ex = Optional.of(this.loggingEvent).map(LogEvent::getThrown).orElse(null);
        if (ex != null) {
            this.exceptionMessage = ex.getMessage();
            this.stackTrace = StackTraceUtils.getStackTrace(ex);
        }
        this.gatherRule.setAlarmLevel(this.message, this.loggerName, this.exceptionMessage, this.stackTrace);
        this.parsingExtendInit = true;
    }
}
